 模板
<template>
  <!-- 媒体查看器遮罩层，点击自身可关闭 -->
  <div class="media-viewer-overlay" @click.self="close">
    <!-- 主媒体显示区域，点击自身也可关闭 -->
    <div class="media-viewer-main" @click.self="close">
      <!-- 图片展示：如果当前链接是图片则渲染 img 标签 -->
      <img v-if="isImage(currentUrl)" :src="currentUrl" class="media-img" />

      <!-- 视频展示容器 -->
      <div v-else class="video-wrapper">
        <!-- 视频播放器，支持控制栏、自动播放 -->
        <video ref="videoRef" controls autoplay class="media-video">
          <!-- 视频源配置，禁用全屏、远程播放和下载功能 -->
          <source controlsList="nofullscreen noremoteplayback nodownload" style="outline:none;" :src="currentUrl" />
        </video>
        <!-- 全屏按钮，用于将视频切换到全屏模式 -->
        <button class="fullscreen-btn" @click.stop="fullscreenVideo">⛶</button>
      </div>

      <!-- 上一张媒体导航按钮（仅在媒体列表长度大于1时显示） -->
      <button v-if="mediaList.length>1" class="nav-btn prev" @click.stop="prev">‹</button>
      <!-- 下一张媒体导航按钮（仅在媒体列表长度大于1时显示） -->
      <button v-if="mediaList.length>1" class="nav-btn next" @click.stop="next">›</button>
      <!-- 关闭媒体查看器按钮 -->
      <button class="close-btn" @click.stop="close">×</button>

      <!-- 可见性选择菜单容器 -->
      <div class="visibility-selector">
        <!-- 可见性选项弹出菜单 -->
        <div class="visibility-menu" v-show="showVisibilityMenu">
          <!-- 遍历可见性选项并渲染每个选项 -->
          <div
            class="visibility-option"
            v-for="option in visibilityOptions"
            :key="option.value"
            @click="selectVisibility(option.value)"
            :class="{ active: visibility === option.value }"
          >
            <!-- 显示图标与标签 -->
            <i :class="option.icon"></i>
            {{ option.label }}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue';

/**
 * 定义组件接收的属性
 */
const props = defineProps({
  /**
   * 媒体资源列表，必须提供
   * @type {Array<string>}
   */
  mediaList: { type: Array, required: true },
  /**
   * 初始索引，默认为 0
   * @type {number}
   */
  initialIndex: { type: Number, default: 0 }
});

/**
 * 定义组件触发的事件
 */
const emit = defineEmits(['close']);

/**
 * 当前媒体项的索引引用
 * @type {import('vue').Ref<number>}
 */
const idx = ref(props.initialIndex);

/**
 * 监听初始索引变化，并同步更新内部索引
 */
watch(() => props.initialIndex, v => { idx.value = v; });

/**
 * 计算当前媒体 URL
 * @returns {string} 当前媒体地址
 */
const currentUrl = computed(() => props.mediaList[idx.value] || '');

/**
 * 视频元素的引用
 * @type {import('vue').Ref<HTMLVideoElement | null>}
 */
const videoRef = ref(null);

/**
 * 判断给定 URL 是否指向一个图像文件
 * @param {string} url - 资源链接
 * @returns {boolean} 如果是图像返回 true，否则 false
 */
function isImage(url) {
  return /\.(jpg|jpeg|png|gif|webp)$/i.test(url);
}

/**
 * 切换至上一项媒体资源
 */
function prev() {
  idx.value = (idx.value - 1 + props.mediaList.length) % props.mediaList.length;
}

/**
 * 切换至下一项媒体资源
 */
function next() {
  idx.value = (idx.value + 1) % props.mediaList.length;
}

/**
 * 发送关闭事件以通知父组件关闭媒体查看器
 */
function close() {
  emit('close');
}

/**
 * 将视频元素请求进入全屏模式（兼容多种浏览器）
 */
function fullscreenVideo() {
  const video = videoRef.value;
  if (video) {
    if (video.requestFullscreen) video.requestFullscreen();
    else if (video.webkitRequestFullscreen) video.webkitRequestFullscreen();
    else if (video.mozRequestFullScreen) video.mozRequestFullScreen();
    else if (video.msRequestFullscreen) video.msRequestFullscreen();
  }
}

/**
 * 处理键盘按键事件，实现左右箭头切换媒体、ESC键退出
 * @param {KeyboardEvent} e - 键盘事件对象
 */
function handleKeydown(e) {
  if (e.key === 'ArrowLeft') prev();
  if (e.key === 'ArrowRight') next();
  if (e.key === 'Escape') close();
}

/**
 * 组件挂载后注册全局键盘监听事件
 */
onMounted(() => window.addEventListener('keydown', handleKeydown));

/**
 * 组件卸载前移除全局键盘监听事件
 */
onBeforeUnmount(() => window.removeEventListener('keydown', handleKeydown));
</script>


<style scoped>
.media-viewer-overlay {
  position: fixed; top:0; left:0; right:0; bottom:0;
  background: rgba(0,0,0,0.75);
  display: flex; align-items: center; justify-content: center;
  z-index: 2000;
}
.media-viewer-main {
  position: fixed;          /* 改为固定定位 */
  top: 0;
  left: 0;
  width: 100vw;             /* 占满整个视口宽度 */
  height: 100vh;            /* 占满整个视口高度 */
  background: transparent;
  border-radius: 0;         /* 移除圆角以适应全屏 */
  box-shadow: none;         /* 移除阴影以避免影响全屏效果 */
  padding: 0;               /* 移除内边距 */
  display: flex;
  align-items: center;
  justify-content: center;
}


.media-img, .media-video {
  max-width: 80vw;
  max-height: 70vh;
  border-radius: 12px;
  background: #000;
  display: block;
  margin: 0 auto;
}
.media-video::-webkit-media-controls-volume-slider,
.media-video::-webkit-media-controls-mute-button,
.media-video::-webkit-media-controls-fullscreen-button,
.media-video::-webkit-media-controls-playback-rate-button,
.media-video::-webkit-media-controls-picture-in-picture-button {
  display: none !important;
}
.nav-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(0,0,0,0.3);
  color: #fff;
  border: none;
  border-radius: 50%;
  width: 44px; height: 44px;
  font-size: 28px;
  cursor: pointer;
  transition: background 0.2s;
  z-index: 10;
  display: flex; align-items: center; justify-content: center;
}
.nav-btn.prev {
  left: 10px;    /* 从 -22px 改为 10px，向右靠拢 */
}

.nav-btn.next {
  right: 10px;   /* 从 -22px 改为 10px，向左靠拢 */
}
.nav-btn:hover { background: #3498db; }
.close-btn {
  position: absolute;
  top: 18px; right: 18px;
  background: rgba(255,255,255,0.75);
  color: #23232b;
  border: none;
  border-radius: 50%;
  width: 40px; height: 40px;
  font-size: 26px;
  font-weight: bold;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, box-shadow 0.2s;
  z-index: 30;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 16px 0 rgba(0,0,0,0.18);
  user-select: none;
}
.close-btn:hover {
  background: rgba(35,35,43,0.85);
  color: #fff;
  box-shadow: 0 8px 24px 0 rgba(44,62,80,0.22);
}
@media (max-width: 600px) {
  .media-viewer-main { padding: 4px; border-radius: 6px; }
  .media-img, .media-video { max-width: 98vw; max-height: 60vh; border-radius: 6px; }
  .nav-btn { width: 32px; height: 32px; font-size: 18px; }
  .close-btn { width: 28px; height: 28px; font-size: 16px; }
}
.visibility-selector {
  position: relative;
  min-width: 120px;
  display: inline-block;
}
.selected-visibility {
  display: flex;
  align-items: center;
  padding: 8px 16px;
  background: #fff;
  border-radius: 20px;
  font-size: 15px;
  cursor: pointer;
  border: 1px solid #e0e0e0;
  color: #23232b;
}
.selected-visibility:hover {
  background: #f0f2f5;
  color: #3498db;
}
.selected-visibility i:first-child {
  margin-right: 8px;
  color: #3498db;
}
.selected-visibility i:last-child {
  margin-left: 8px;
  font-size: 12px;
}
.visibility-menu {
  position: absolute;
  top: 110%;
  left: 0;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(44,62,80,0.10);
  z-index: 10;
  min-width: 140px;
  overflow: hidden;
  margin-top: 4px;
  border: 1px solid #e0e0e0;
}
.visibility-option {
  padding: 12px 18px;
  display: flex;
  align-items: center;
  font-size: 15px;
  cursor: pointer;
  background: #fff;
  color: #23232b;
  transition: background 0.2s, color 0.2s;
}
.visibility-option i {
  margin-right: 10px;
  color: #3498db;
}
.visibility-option:hover,
.visibility-option.active {
  background: #eaf6fd;
  color: #3498db;
}
/* 黑色按钮通用样式 */
.black-btn {
  background: #232323;
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 10px 20px;
  font-size: 16px;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.black-btn:hover, .black-btn:focus {
  background: #fff;
  color: #232323;
  border: 1px solid #232323;
}
.video-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.fullscreen-btn {
  position: absolute;
  top: 12px;
  right: 12px;
  background: rgba(0,0,0,0.25);
  color: #fff;
  border: none;
  border-radius: 6px;
  width: 32px;
  height: 32px;
  font-size: 18px;
  cursor: pointer;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s, color 0.2s;
}
.fullscreen-btn:hover {
  background: #3498db;
  color: #fff;
}
.visibility-option.active {
  background: #eaf6fd;
}
</style>